Skip to content

React Native TV support#239

Merged
xavi160 merged 13 commits into
mainfrom
next
Jun 30, 2026
Merged

React Native TV support#239
xavi160 merged 13 commits into
mainfrom
next

Conversation

@xavi160

@xavi160 xavi160 commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

This branch bundles the next major release of the spatial navigation packages. The headline changes are first-class React Native TV support via a new adapter package, a move to async layout measurement in core, and a new nextFocusResolver hook for overriding focus decisions. It also removes the old nativeMode flag in favor of adapter-based platform selection.

What's changed

New features

  • React Native TV support — added a new workspace, @noriginmedia/norigin-spatial-navigation-react-native-tvos, with ReactNativeLayoutAdapter that wires native layout measurement and remote/D-pad input into the same useFocusable API used on the web. docs/guides/react-native-tv.md
  • Async layout measurementmeasureLayout and the internal focus pipeline now operate asynchronously. A new Scheduler class in packages/core/src/Scheduler.ts guarantees that async tasks run in strict order so focus races are avoided.
  • Adapter-based platform configuration — replaced the useGetBoundingClientRect init flag with a layoutAdapter option. Core now exports BaseWebAdapter and GetBoundingClientRectAdapter for custom or legacy web setups. packages/core/src/adapter/web.ts
  • nextFocusResolver — focusable nodes can now override the engine's default directional choice by returning a custom focus key from nextFocusResolver(direction, focusDetails). docs/api-reference/useFocusable.md
  • Configurable focus-on-preset-key behavior — the behavior triggered by preset keys can now be customized.
  • Decoupled event listeners and focus management — event handling is separated from focus state logic, making adapters and custom inputs easier to implement.

Breaking changes

Before After
init({ nativeMode: true }) init({ layoutAdapter: ReactNativeLayoutAdapter })
init({ useGetBoundingClientRect: true }) init({ layoutAdapter: GetBoundingClientRectAdapter }) (still accepted but deprecated)
SpatialNavigationService.isNativeMode() Removed; inspect the active layoutAdapter instead
Synchronous measureLayout Async measureLayout

xavi160 and others added 13 commits June 18, 2026 15:34
* chore: add test step in prs
- Fixed jest setup to work with lodash-es using babel

* feat: measuring layout is now async

* refactor: rename layout adapter constants and introduce getBoundingClientRectAdapter

* chore: add changeset

* docs: update SpatialNavigation and related guides to reflect deprecation of useGetBoundingClientRect and introduce layoutAdapter for improved layout measurement

* fix: replace unused layoutUpdate with layoutUpdatedAt timestamp to avoid unnecessary layout updates

* feat: implement Scheduler class

* fix: await smartNavigate in SpatialNavigationService to ensure proper asynchronous behavior

* refactor: setFocus async

* fix: handle undefined currentTask in Scheduler

* fix: correct layout update condition in SpatialNavigationService to ensure proper component updates

* docs: document Scheduler class changees

* fix: initialize layoutUpdatedAt in SpatialNavigationService to ensure proper layout updates

* fix: ensure currentTask is not triggered twice

* fix: revert previous changes. Remove tick from priority tasks, add a try / finally block to the currentTask execution
* chore: update ESLint configuration to disable rules

* feat: expand LayoutAdapter interface and refactor SpatialNavigationService to support custom event listeners

* refactor: implement blurNode and update focusNode methods in LayoutAdapter for improved spatial navigation handling

* feat: re-export adapters

* docs: update SpatialNavigation and debugging guides to reflect new layout adapter usage

* fix: await smartNavigate in keyDownEventListener to ensure proper behavior

* fix: ensure data-focused attribute is set

* feat: remove support for LayoutAdapter instance, use constructor option instead
* feat: add NodeType interface and update FocusableComponent to support custom node types

* feat: introduce ReactNativeLayoutAdapter

* refactor: update ReactNativeLayoutAdapter to conditionally export based on platform

* refactor: remove nativeMode from SpatialNavigationService and related options

- Eliminated nativeMode property from SpatialNavigationServiceOptions and its usage throughout the service.
- Updated related logic to ensure functionality remains intact without nativeMode.
- Cleaned up code for improved readability and maintainability.

* docs: enhance React Native TV support and update related documentation

- Updated README.md to reflect full support for Android TV and Apple TV using the `@noriginmedia/norigin-spatial-navigation-react-native` package.
- Revised SpatialNavigation.md to clarify the use of layout adapters and introduced new sections for React Native TV, including installation and initialization instructions.
- Expanded useFocusable.md to specify the differences in ref handling between web and React Native TV.
- Added a new guide for React Native TV detailing setup and usage.
- Adjusted installation.md to include peer dependencies for React Native TV.

* feat: add NodeTypeOverrides interface and enhance ReactNativeLayoutAdapter for improved customization

* fix: add missing external dependencies in rollup configuration for React Native

* fix: resolve undefined layout for Android TV with EMPTY_LAYOUT constant

* chore: update TypeScript configuration for React Native to skip library checks
…ing with React Native Web (#230)

* feat: enhance rollup configuration and add web-specific entry point

- Updated rollup configuration to support separate builds for web and common JS formats.
- Added new entry point for web-specific functionality in src/index.web.ts.
- Updated package.json exports to include web module paths.
* feat: add navigationStrategy to FocusableComponent and update SpatialNavigationService for custom navigation handling

* refactor: rename navigationStrategy to nextFocusResolver

* Create hot-falcons-begin.md

* fix: add warning for invalid component in nextFocusResolver to prevent lost focus

* Update packages/core/src/SpatialNavigation.ts

Co-authored-by: Dmitriy Bryokhin <2877657+asgvard@users.noreply.github.com>

---------

Co-authored-by: Dmitriy Bryokhin <2877657+asgvard@users.noreply.github.com>
@xavi160
xavi160 requested a review from a team as a code owner June 19, 2026 12:22
@changeset-bot

changeset-bot Bot commented Jun 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: eb5d699

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@noriginmedia/norigin-spatial-navigation-core Major
@noriginmedia/norigin-spatial-navigation-react-native-tvos Major
@noriginmedia/norigin-spatial-navigation-react Patch
@noriginmedia/norigin-spatial-navigation Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@xavi160 xavi160 self-assigned this Jun 19, 2026
@xavi160 xavi160 added documentation Improvements or additions to documentation enhancement New feature or request labels Jun 19, 2026

@AdriVelazquezNorigin AdriVelazquezNorigin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@predikament predikament left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to leave my review when I checked this earlier - Looks fine to me 👍🏻

@xavi160
xavi160 merged commit 54353b0 into main Jun 30, 2026
1 check passed
@xavi160
xavi160 deleted the next branch June 30, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants